#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pthread.h"
#define BUFFER_SIZE 16
#define OVER (-1)
struct prodcons
{
int buffer[BUFFER_SIZE];
pthread_mutex_t lock;
int readpos,writepos;
pthread_cond_t notempty;
pthread_cond_t notfull;
};
struct prodcons buffer; 
void init(struct prodcons *b)
{
pthread_mutex_init(&b->lock,NULL);
pthread_cond_init(&b->notempty,NULL);
pthread_cond_init(&b->notfull,NULL);
b->readpos=0;
b->writepos=0;
}
void put(struct prodcons *b,int data)
{
pthread_mutex_lock(&b->lock);//申请对buffer资源区加锁
while((b->writepos+1)%BUFFER_SIZE==b->readpos)
 {
 printf("wait for not full\n");
 pthread_cond_wait(&b->notfull,&b->lock); //资源池满,等待释放资源池中的一个位置
 }
b->buffer[b->writepos]=data;
b->writepos++;//生产者position +1
if(b->writepos>=BUFFER_SIZE) b->writepos=0;//生产者pos到顶重回资源池初始位置
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->lock);//对buffer资源区解锁
}
int get(struct prodcons *b)
{
int data;
pthread_mutex_lock(&b->lock);//申请对buffer资源区加锁
while(b->writepos==b->readpos)
 {
 printf("wait for not empty\n");
 pthread_cond_wait(&b->notempty,&b->lock);
 }
data=b->buffer[b->readpos];
b->readpos++;
if(b->readpos>=BUFFER_SIZE) b->readpos=0;
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->lock);//对buffer资源区解锁
return data;
}
void *producer(void *data)
{
int n; 
for(n=0;n<150;n++)
 {
 printf("put---->%d\n",n);
 put(&buffer,n);
 }
put(&buffer,OVER);
printf("producer stopped!!\n");
return NULL;
}
void *consumer(void *data)
{
int d;
while(1)
 {
 d=get(&buffer);//获取buffer里面的数据
 if(d==OVER) break;//如果到OVER就停止
 printf("%d----->get\n",d);
 }
printf("consumer stopped!!\n");
return NULL;
}
int main(void)
{
pthread_t th_a,th_b;
void *retval;
init(&buffer);
pthread_create(&th_a,NULL,producer,0);
pthread_create(&th_b,NULL,consumer,0);
pthread_join(th_a,&retval);
pthread_join(th_b,&retval);
return 0;
}